<template>
  <div class="module-card">
    <div class="module-header">
      <div class="header-left">
        <h3>
          <i class="icon-calendar"></i>
          排班管理
        </h3>
        <p class="header-subtitle">为采播部成员安排播稿时间</p>
      </div>
      <div class="header-controls">
        <button @click="openWeekStartDialog" class="btn-secondary">
          <i class="icon-settings"></i>
          设置起始周
        </button>
        <div class="week-navigation">
          <button @click="prevWeek" :disabled="currentWeek <= 1" class="btn-nav">
            <i class="icon-chevron-left"></i>
          </button>
          <div class="week-indicator">
            <span class="week-number">第{{ currentWeek }}周</span>
            <span class="week-dates">{{ weekDateRange }}</span>
          </div>
          <button @click="nextWeek" class="btn-nav">
            <i class="icon-chevron-right"></i>
          </button>
        </div>
      </div>
    </div>
    
    <div v-if="loading" class="loading-container">
      <div class="loading-spinner"></div>
      <p>正在加载排班数据...</p>
    </div>
    
    <div v-else class="calendar-container">
      <div class="calendar-header">
        <div class="calendar-cell time-header">
          <i class="icon-clock"></i>
          <span>时间</span>
        </div>
        <div class="calendar-cell day-header" v-for="(day, index) in weekDays" :key="day">
          <div class="day-name">{{ day }}</div>
          <div class="day-date">{{ formatDate(weekDates[index]) }}</div>
        </div>
      </div>
      <div class="calendar-body">
        <div class="calendar-row" v-for="time in broadcastTimes" :key="time">
          <div class="calendar-cell time-cell">
            <div class="time-display">
              <i class="icon-time"></i>
              <span>{{ time }}</span>
            </div>
          </div>
          <div class="calendar-cell schedule-cell" v-for="(day, dayIndex) in weekDays" :key="`${day}-${time}`">
            <div class="schedule-item" v-if="getScheduleItem(day, time)">
              <div class="schedule-header">
                <div class="theme-badge">{{ getScheduleItem(day, time).topic }}</div>
                <div class="schedule-actions">
                  <button @click="handleEditSchedule(getScheduleItem(day, time))" class="action-btn edit-btn" title="编辑">
                    <i class="icon-edit"></i>
                  </button>
                  <button @click="handleDeleteSchedule(getScheduleItem(day, time).scheduleId)" class="action-btn delete-btn" title="删除">
                    <i class="icon-trash"></i>
                  </button>
                </div>
              </div>
              <div class="partners-info">
                <i class="icon-users"></i>
                <span class="partners-text">
                  {{ getScheduleItem(day, time).partner1_name }}
                  <span v-if="getScheduleItem(day, time).partner2_name">、{{ getScheduleItem(day, time).partner2_name }}</span>
                </span>
              </div>
            </div>
            <div class="empty-schedule" v-else>
              <button @click="handleAddSchedule(day, time, weekDates[dayIndex])" class="add-schedule-btn">
                <i class="icon-plus"></i>
                <span>添加排班</span>
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <div class="theme-section">
      <div class="theme-header">
        <h4>
          <i class="icon-tag"></i>
          可用播稿主题
        </h4>
        <span class="theme-count">{{ allThemes.length }} 个主题</span>
      </div>
      <div class="theme-tags" v-if="allThemes.length > 0">
        <span v-for="theme in allThemes" :key="theme" class="theme-tag">
          <i class="icon-bookmark"></i>
          {{ theme }}
        </span>
      </div>
      <div v-else class="no-themes">
        <i class="icon-info-circle"></i>
        <p>暂无可用主题，请联系管理员添加</p>
      </div>
    </div>
    
    <!-- 排班编辑对话框 -->
    <div v-if="showEditDialog" class="dialog-overlay">
      <div class="dialog schedule-dialog">
        <div class="dialog-header">
          <div class="dialog-title">
            <i class="icon-calendar-plus"></i>
            <h3>{{ editingSchedule ? '编辑排班' : '添加排班' }}</h3>
          </div>
          <button @click="closeDialog" class="dialog-close">
            <i class="icon-close"></i>
          </button>
        </div>
        <div class="dialog-content">
          <div class="form-row">
            <div class="form-group">
              <label>
                <i class="icon-calendar"></i>
                日期
              </label>
              <input type="date" v-model="scheduleForm.date" disabled class="form-input">
            </div>
            <div class="form-group">
              <label>
                <i class="icon-clock"></i>
                时间
              </label>
              <select v-model="scheduleForm.time" class="form-select">
                <option v-for="time in broadcastTimes" :key="time" :value="time">{{ time }}</option>
              </select>
            </div>
          </div>
          
          <div class="form-group">
            <label>
              <i class="icon-tag"></i>
              播稿主题
            </label>
            <div class="input-with-suggestions">
              <input 
                v-model="scheduleForm.topic" 
                list="theme-list" 
                placeholder="请输入或选择主题"
                class="form-input"
              >
              <datalist id="theme-list">
                <option v-for="theme in allThemes" :key="theme" :value="theme">{{ theme }}</option>
              </datalist>
            </div>
          </div>
          
          <div class="form-row">
            <div class="form-group">
              <label>
                <i class="icon-user"></i>
                搭档1 <span class="required">*</span>
              </label>
              <select v-model="scheduleForm.partner1Id" class="form-select" required>
                <option value="">请选择搭档1</option>
                <option 
                  v-for="user in departmentUsers" 
                  :key="user.id" 
                  :value="user.id"
                >
                  {{ user.username }} ({{ user.position }})
                </option>
              </select>
            </div>
            <div class="form-group">
              <label>
                <i class="icon-users"></i>
                搭档2 <span class="optional">(可选)</span>
              </label>
              <select v-model="scheduleForm.partner2Id" class="form-select">
                <option value="">请选择搭档2</option>
                <option 
                  v-for="user in departmentUsers" 
                  :key="user.id" 
                  :value="user.id"
                >
                  {{ user.username }} ({{ user.position }})
                </option>
              </select>
            </div>
          </div>
        </div>
        <div class="dialog-footer">
          <button @click="closeDialog" class="btn-secondary">
            <i class="icon-close"></i>
            取消
          </button>
          <button @click="submitSchedule" class="btn-primary">
            <i class="icon-save"></i>
            {{ editingSchedule ? '更新' : '保存' }}
          </button>
        </div>
      </div>
    </div>
    
    <!-- 设置起始周对话框 -->
    <div v-if="showWeekStartDialog" class="dialog-overlay">
      <div class="dialog week-dialog">
        <div class="dialog-header">
          <div class="dialog-title">
            <i class="icon-calendar-check"></i>
            <h3>设置起始周</h3>
          </div>
          <button @click="closeWeekStartDialog" class="dialog-close">
            <i class="icon-close"></i>
          </button>
        </div>
        <div class="dialog-content">
          <div class="form-group">
            <label>
              <i class="icon-calendar"></i>
              请选择第一周的起始日期
            </label>
            <input type="date" v-model="weekStartForm.date" class="form-input">
            <p class="form-hint">选择日期后，系统将以此日期为第一周的周一重新计算周次</p>
          </div>
        </div>
        <div class="dialog-footer">
          <button @click="closeWeekStartDialog" class="btn-secondary">
            <i class="icon-close"></i>
            取消
          </button>
          <button @click="setWeekStart" class="btn-primary">
            <i class="icon-check"></i>
            确定
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, watch } from 'vue'

const currentWeek = ref(1)
const weekDays = ['周一', '周二', '周三', '周四', '周五']
const broadcastTimes = ['12:00', '17:20']
const allThemes = ref([])
const schedules = ref([])
const departmentUsers = ref([])
const loading = ref(false)
const showEditDialog = ref(false)
const showWeekStartDialog = ref(false)
const editingSchedule = ref(null)

const weekStartForm = ref({
  date: ''
})

const scheduleForm = ref({
  date: '',
  time: '12:00',
  topic: '',
  partner1Id: null,
  partner2Id: null
})

const customStartDate = ref(null)

const weekDates = computed(() => {
  const dates = []
  let startDate
  
  if (customStartDate.value) {
    startDate = new Date(customStartDate.value)
    startDate.setDate(startDate.getDate() + (currentWeek.value - 1) * 7)
  } else {
    const currentDate = new Date()
    const firstDayOfYear = new Date(currentDate.getFullYear(), 0, 1)
    const pastDaysOfYear = (currentDate - firstDayOfYear) / 86400000
    const currentWeekNum = Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7)
    
    startDate = new Date(currentDate)
    startDate.setDate(startDate.getDate() - (currentDate.getDay() || 7) + 1 + (currentWeek.value - currentWeekNum) * 7)
  }
  
  for (let i = 0; i < 5; i++) {
    const date = new Date(startDate)
    date.setDate(date.getDate() + i)
    dates.push(date)
  }
  
  return dates
})

const weekDateRange = computed(() => {
  if (weekDates.value.length < 5) return ''
  const start = formatDate(weekDates.value[0])
  const end = formatDate(weekDates.value[4])
  return `${start} 至 ${end}`
})

const fetchSchedules = async () => {
  loading.value = true
  try {
    // 添加时间戳防止缓存
    const response = await fetch(`http://localhost:8080/schedule/week/${currentWeek.value}?_=${Date.now()}`)
    const result = await response.json()
    
    console.log('获取排班数据响应:', result)
    
    if (result.code === 200) {
      // 转换数据格式，添加安全检查
      schedules.value = (result.data || []).map(item => {
        if (!item || !item.date) {
          console.warn('无效的排班数据项:', item)
          return null
        }
        
        try {
          const date = new Date(item.date)
          return {
            ...item,
            day: getDayOfWeek(date),
            time: getTimeFromDate(date)
          }
        } catch (error) {
          console.error('解析排班日期失败:', item.date, error)
          return null
        }
      }).filter(item => item !== null) // 过滤掉无效项
      
      console.log('处理后的排班数据:', schedules.value)
    } else {
      console.error('获取排班数据失败:', result.message)
      showToast(result.message || '获取排班数据失败', 'error')
    }
  } catch (error) {
    console.error('获取排班数据失败:', error)
    showToast('获取排班数据失败，请重试', 'error')
  } finally {
    loading.value = false
  }
}

const fetchAllThemes = async () => {
  try {
    const response = await fetch('http://localhost:8080/topicLibrary/department/1')
    const result = await response.json()
    if (result.code === 200) {
      allThemes.value = result.data.map(t => t.topicName)
    }
  } catch (error) {
    console.error('获取播稿主题失败:', error)
  }
}

const fetchDepartmentUsers = async () => {
  try {
    const response = await fetch('http://localhost:8080/user/department/1')
    const result = await response.json()
    if (result.code === 200) {
      departmentUsers.value = result.data
    }
  } catch (error) {
    console.error('获取部门成员失败:', error)
  }
}

const getDayOfWeek = (date) => {
  const days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
  return days[date.getDay()]
}

const getTimeFromDate = (date) => {
  const hours = date.getHours().toString().padStart(2, '0')
  const minutes = date.getMinutes().toString().padStart(2, '0')
  return `${hours}:${minutes}`
}

const formatDate = (date) => {
  if (!date) return ''
  const d = new Date(date)
  return `${d.getMonth() + 1}月${d.getDate()}日`
}

const getScheduleItem = (day, time) => {
  const normalizedDay = day.replace('星期', '周') // 统一格式
  
  const item = schedules.value.find(item => {
    return item && item.day === normalizedDay && item.time === time
  })
  
  if (!item) return null
  
  return {
    ...item,
    partner1_name: departmentUsers.value.find(u => u && u.id === item.partner1Id)?.username || '',
    partner2_name: departmentUsers.value.find(u => u && u.id === item.partner2Id)?.username || ''
  }
}

const prevWeek = () => {
  if (currentWeek.value > 1) {
    currentWeek.value--
  }
}

const nextWeek = () => {
  currentWeek.value++
}

const openWeekStartDialog = () => {
  weekStartForm.value.date = customStartDate.value || new Date().toISOString().split('T')[0]
  showWeekStartDialog.value = true
}

const closeWeekStartDialog = () => {
  showWeekStartDialog.value = false
}

const setWeekStart = () => {
  if (weekStartForm.value.date) {
    customStartDate.value = weekStartForm.value.date
    currentWeek.value = 1
    closeWeekStartDialog()
    fetchSchedules() // 重新加载数据
  }
}

const handleAddSchedule = (day, time, date) => {
  editingSchedule.value = null
  scheduleForm.value = {
    date: date.toISOString().split('T')[0],
    time: time,
    topic: '',
    partner1Id: null,
    partner2Id: null
  }
  showEditDialog.value = true
}

const handleEditSchedule = (schedule) => {
  editingSchedule.value = schedule
  scheduleForm.value = {
    date: new Date(schedule.date).toISOString().split('T')[0],
    time: schedule.time,
    topic: schedule.topic,
    partner1Id: schedule.partner1Id || null,
    partner2Id: schedule.partner2Id || null
  }
  showEditDialog.value = true
}

const handleDeleteSchedule = async (scheduleId) => {
  if (!confirm('确定要删除这个排班吗？删除后无法恢复。')) return
  
  try {
    console.log('准备删除排班ID:', scheduleId, '类型:', typeof scheduleId)
    
    // 检查是否是临时ID（前端生成的）
    if (typeof scheduleId === 'string' && scheduleId.startsWith('temp_')) {
      console.log('检测到临时ID，直接从前端删除')
      schedules.value = schedules.value.filter(s => s.scheduleId !== scheduleId)
      showToast('排班删除成功', 'success')
      return
    }
    
    // 尝试不同的删除API端点
    const deleteEndpoints = [
      `http://localhost:8080/schedule/delete/${scheduleId}`,
      `http://localhost:8080/schedule/${scheduleId}`,
      `http://localhost:8080/schedule/remove/${scheduleId}`
    ]
    
    let deleteSuccess = false
    
    for (const deleteUrl of deleteEndpoints) {
      try {
        console.log('尝试删除端点:', deleteUrl)
        
        const response = await fetch(deleteUrl, {
          method: 'DELETE',
          headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json'
          }
        })
        
        console.log('删除响应状态:', response.status)
        
        if (response.ok) {
          const result = await response.json()
          console.log('删除响应结果:', result)
          
          if (result.code === 200) {
            schedules.value = schedules.value.filter(s => s.scheduleId !== scheduleId)
            showToast('排班删除成功', 'success')
            deleteSuccess = true
            break
          }
        }
      } catch (endpointError) {
        console.log('端点删除失败:', deleteUrl, endpointError)
        continue
      }
    }
    
    // 如果所有DELETE端点都失败，尝试POST方法
    if (!deleteSuccess) {
      console.log('尝试POST方法删除...')
      try {
        const postResponse = await fetch('http://localhost:8080/schedule/delete', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json'
          },
          body: JSON.stringify({ 
            scheduleId: scheduleId,
            id: scheduleId  // 有些API可能使用id字段
          })
        })
        
        const postResult = await postResponse.json()
        console.log('POST删除响应:', postResult)
        
        if (postResult.code === 200) {
          schedules.value = schedules.value.filter(s => s.scheduleId !== scheduleId)
          showToast('排班删除成功', 'success')
          deleteSuccess = true
        }
      } catch (postError) {
        console.log('POST删除也失败:', postError)
      }
    }
    
    if (!deleteSuccess) {
      showToast('删除排班失败，请检查网络连接或联系管理员', 'error')
    }
    
  } catch (error) {
    console.error('删除排班失败:', error)
    showToast('删除排班失败，请重试', 'error')
  }
}

const submitSchedule = async () => {
  try {
    // 数据验证
    if (!scheduleForm.value.topic?.trim()) {
      showToast('请输入播稿主题', 'warning')
      return
    }
    
    if (!scheduleForm.value.partner1Id) {
      showToast('请选择搭档1', 'warning')
      return
    }
    
    // 检查搭档是否重复
    if (scheduleForm.value.partner1Id === scheduleForm.value.partner2Id) {
      showToast('搭档1和搭档2不能是同一个人', 'warning')
      return
    }
    
    // 检查是否在同一时间段已有排班
    const existingSchedule = schedules.value.find(s => {
      const scheduleDate = new Date(s.date)
      const formDate = new Date(`${scheduleForm.value.date}T${scheduleForm.value.time}:00`)
      return scheduleDate.getTime() === formDate.getTime() && 
             s.scheduleId !== editingSchedule.value?.scheduleId
    })
    
    if (existingSchedule) {
      showToast('该时间段已有排班安排', 'warning')
      return
    }
    
    // 构建完整的ISO日期时间字符串
    const dateTime = `${scheduleForm.value.date}T${scheduleForm.value.time}:00`
    
    const scheduleData = {
      departmentId: 1,
      week: currentWeek.value,
      date: dateTime,
      topic: scheduleForm.value.topic.trim(),
      partner1Id: scheduleForm.value.partner1Id,
      partner2Id: scheduleForm.value.partner2Id || null,
      status: 'scheduled'
    }
    
    if (editingSchedule.value) {
      scheduleData.scheduleId = editingSchedule.value.scheduleId
    }
    
    const url = editingSchedule.value 
      ? 'http://localhost:8080/schedule/update' 
      : 'http://localhost:8080/schedule/add'
    
    const method = editingSchedule.value ? 'PUT' : 'POST'
    
    // 显示加载状态
    const submitBtn = document.querySelector('.btn-primary')
    const originalText = submitBtn.innerHTML
    submitBtn.innerHTML = '<i class="icon-loading"></i> 保存中...'
    submitBtn.disabled = true
    
    const response = await fetch(url, {
      method,
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(scheduleData)
    })
    
    const result = await response.json()
    
    // 恢复按钮状态
    submitBtn.innerHTML = originalText
    submitBtn.disabled = false
    
    // 调试信息
    console.log('API响应结果:', result)
    
    if (result.code === 200) {
      // 成功后的处理
      if (editingSchedule.value) {
        // 更新现有排班
        const index = schedules.value.findIndex(s => s.scheduleId === editingSchedule.value.scheduleId)
        if (index !== -1) {
          // 使用表单数据构建更新项，因为后端可能不返回完整数据
          const updatedItem = {
            ...schedules.value[index],
            ...result.data,
            topic: scheduleForm.value.topic.trim(),
            partner1Id: scheduleForm.value.partner1Id,
            partner2Id: scheduleForm.value.partner2Id || null,
            day: getDayOfWeek(new Date(`${scheduleForm.value.date}T${scheduleForm.value.time}:00`)),
            time: scheduleForm.value.time
          }
          schedules.value.splice(index, 1, updatedItem)
        }
        showToast('排班更新成功', 'success')
      } else {
        // 添加新排班
        const newItem = {
          scheduleId: result.data?.scheduleId || result.data?.id || `temp_${Date.now()}`, // 使用返回的ID或生成临时ID
          departmentId: 1,
          week: currentWeek.value,
          date: `${scheduleForm.value.date}T${scheduleForm.value.time}:00`,
          topic: scheduleForm.value.topic.trim(),
          partner1Id: scheduleForm.value.partner1Id,
          partner2Id: scheduleForm.value.partner2Id || null,
          status: 'scheduled',
          day: getDayOfWeek(new Date(`${scheduleForm.value.date}T${scheduleForm.value.time}:00`)),
          time: scheduleForm.value.time
        }
        schedules.value.push(newItem)
        showToast('排班添加成功', 'success')
      }
      
      closeDialog()
    } else {
      showToast(result.message || '操作失败', 'error')
    }
  } catch (error) {
    console.error('操作排班失败:', error)
    showToast(`操作排班失败: ${error.message}`, 'error')
    
    // 恢复按钮状态
    const submitBtn = document.querySelector('.btn-primary')
    if (submitBtn) {
      submitBtn.innerHTML = editingSchedule.value ? '<i class="icon-save"></i> 更新' : '<i class="icon-save"></i> 保存'
      submitBtn.disabled = false
    }
  }
}

const closeDialog = () => {
  showEditDialog.value = false
  editingSchedule.value = null
}

// 提示消息函数
const showToast = (message, type = 'info') => {
  // 创建toast元素
  const toast = document.createElement('div')
  toast.className = `toast ${type}`
  toast.innerHTML = `
    <div class="toast-content">
      <i class="toast-icon icon-${getToastIcon(type)}"></i>
      <span class="toast-message">${message}</span>
    </div>
  `
  document.body.appendChild(toast)
  
  // 显示动画
  setTimeout(() => {
    toast.classList.add('show')
  }, 10)
  
  // 自动消失
  setTimeout(() => {
    toast.classList.remove('show')
    setTimeout(() => {
      if (document.body.contains(toast)) {
        document.body.removeChild(toast)
      }
    }, 300)
  }, 3000)
}

// 获取toast图标
const getToastIcon = (type) => {
  const icons = {
    success: 'check-circle',
    error: 'close-circle',
    warning: 'exclamation-circle',
    info: 'info-circle'
  }
  return icons[type] || 'info-circle'
}

// 监听周次变化
watch(currentWeek, fetchSchedules)

// 初始化数据
onMounted(() => {
  fetchSchedules()
  fetchAllThemes()
  fetchDepartmentUsers()
})
</script>

<style scoped>
/* 删除外部字体图标引入 */
/* @import url("//at.alicdn.com/t/font_1678909_4p2z5e3l8h.css"); */

.module-card {
  max-width: 90%;
  width: 100%;
  max-width: none;
  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
  border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

/* 头部样式 */
.module-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  padding: 24px 24px 20px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border-radius: 12px 12px 0 0;
  margin: -1px -1px 0 -1px;
}

.header-left h3 {
  margin: 0 0 8px 0;
  font-size: 24px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 12px;
}

.header-left h3 i {
  font-size: 28px;
  opacity: 0.9;
}

.header-subtitle {
  margin: 0;
  opacity: 0.8;
  font-size: 14px;
  font-weight: 400;
}

.header-controls {
  display: flex;
  flex-direction: column;
  gap: 16px;
  align-items: flex-end;
}

.week-navigation {
  display: flex;
  align-items: center;
  background: rgba(255, 255, 255, 0.15);
  border-radius: 8px;
  padding: 4px;
  backdrop-filter: blur(10px);
}

.btn-nav {
  background: none;
  border: none;
  color: white;
  padding: 8px 12px;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  justify-content: center;
}

.btn-nav:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.2);
  transform: scale(1.05);
}

.btn-nav:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.week-indicator {
  padding: 0 16px;
  text-align: center;
  min-width: 200px;
}

.week-number {
  display: block;
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 2px;
}

.week-dates {
  display: block;
  font-size: 12px;
  opacity: 0.8;
}

.btn-secondary {
  background: rgba(255, 255, 255, 0.15);
  color: white;
  border: 1px solid rgba(255, 255, 255, 0.2);
  padding: 10px 16px;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  backdrop-filter: blur(10px);
}

.btn-secondary:hover {
  background: rgba(255, 255, 255, 0.25);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

/* 加载状态 */
.loading-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 20px;
  color: #666;
}

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 3px solid #f3f3f3;
  border-top: 3px solid #667eea;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 16px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* 日历容器 */
.calendar-container {
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  overflow: hidden;
  margin: 24px 0;
  background: white;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.calendar-header {
  display: flex;
  background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
  border-bottom: 2px solid #e2e8f0;
}

.calendar-body {
  background: white;
}

.calendar-row {
  display: flex;
  border-bottom: 1px solid #f1f5f9;
  transition: background-color 0.2s ease;
}

.calendar-row:hover {
  background-color: #f8fafc;
}

.calendar-row:last-child {
  border-bottom: none;
}

.calendar-cell {
  flex: 1;
  padding: 16px;
  border-right: 1px solid #f1f5f9;
  min-height: 120px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.calendar-cell:last-child {
  border-right: none;
}

.time-header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 100px;
  flex: 0 0 auto;
}

.day-header {
  background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
  text-align: center;
  padding: 16px 12px;
  min-width: 120px;
}

.day-name {
  font-weight: 600;
  color: #2d3748;
  margin-bottom: 4px;
  font-size: 14px;
}

.day-date {
  font-size: 12px;
  color: #718096;
}

.time-cell {
  background: linear-gradient(135deg, #f7fafc 0%, #edf2f7 100%);
  font-weight: 600;
  min-width: 100px;
  flex: 0 0 auto;
  border-right: 2px solid #e2e8f0;
}

.time-display {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  color: #4a5568;
}

.time-display i {
  font-size: 16px;
  opacity: 0.7;
}

.schedule-cell {
  padding: 12px;
  min-height: 120px;
  position: relative;
}

/* 排班项样式 */
.schedule-item {
  background: linear-gradient(135deg, #e6f7ff 0%, #bae7ff 100%);
  border: 2px solid #1890ff;
  border-radius: 8px;
  padding: 12px;
  height: 100%;
  box-shadow: 0 2px 8px rgba(24, 144, 255, 0.15);
  transition: all 0.3s ease;
  position: relative;
  overflow: hidden;
}

.schedule-item::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, #1890ff, #40a9ff);
}

.schedule-item:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(24, 144, 255, 0.25);
}

.schedule-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 8px;
}

.theme-badge {
  background: linear-gradient(135deg, #1890ff, #40a9ff);
  color: white;
  padding: 4px 8px;
  border-radius: 12px;
  font-size: 11px;
  font-weight: 600;
  max-width: 80%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.schedule-actions {
  display: flex;
  gap: 4px;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.schedule-item:hover .schedule-actions {
  opacity: 1;
}

.action-btn {
  background: none;
  border: none;
  padding: 4px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
}

.edit-btn {
  color: #1890ff;
  background: rgba(24, 144, 255, 0.1);
}

.edit-btn:hover {
  background: #1890ff;
  color: white;
  transform: scale(1.1);
}

.delete-btn {
  color: #ff4d4f;
  background: rgba(255, 77, 79, 0.1);
}

.delete-btn:hover {
  background: #ff4d4f;
  color: white;
  transform: scale(1.1);
}

.partners-info {
  display: flex;
  align-items: center;
  gap: 6px;
  color: #4a5568;
  font-size: 12px;
}

.partners-info i {
  color: #718096;
  font-size: 14px;
}

.partners-text {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 空排班样式 */
.empty-schedule {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
  border: 2px dashed #cbd5e0;
  border-radius: 8px;
  transition: all 0.3s ease;
}

.empty-schedule:hover {
  background: linear-gradient(135deg, #e6f7ff 0%, #bae7ff 100%);
  border-color: #1890ff;
}

.add-schedule-btn {
  background: none;
  border: none;
  color: #718096;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 12px;
  transition: all 0.3s ease;
  font-size: 12px;
}

.add-schedule-btn:hover {
  color: #1890ff;
  transform: scale(1.05);
}

.add-schedule-btn i {
  font-size: 20px;
  opacity: 0.7;
}

/* 主题列表样式 */
.theme-section {
  margin-top: 24px;
  padding: 20px;
  background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
  border-radius: 12px;
  border: 1px solid #e2e8f0;
}

.theme-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.theme-header h4 {
  margin: 0;
  color: #2d3748;
  font-size: 16px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
}

.theme-header h4 i {
  color: #667eea;
  font-size: 18px;
}

.theme-count {
  background: linear-gradient(135deg, #667eea, #764ba2);
  color: white;
  padding: 4px 12px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 500;
}

.theme-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.theme-tag {
  background: linear-gradient(135deg, #e6f7ff 0%, #bae7ff 100%);
  color: #1890ff;
  padding: 6px 12px;
  border-radius: 16px;
  font-size: 12px;
  font-weight: 500;
  border: 1px solid rgba(24, 144, 255, 0.2);
  display: flex;
  align-items: center;
  gap: 4px;
  transition: all 0.3s ease;
}

.theme-tag:hover {
  background: linear-gradient(135deg, #1890ff, #40a9ff);
  color: white;
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(24, 144, 255, 0.3);
}

.theme-tag i {
  font-size: 10px;
}

.no-themes {
  text-align: center;
  padding: 20px;
  color: #718096;
}

.no-themes i {
  font-size: 24px;
  margin-bottom: 8px;
  opacity: 0.6;
}

.no-themes p {
  margin: 0;
  font-size: 14px;
}

/* 对话框样式 */
.dialog-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  animation: fadeIn 0.3s ease;
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

.dialog {
  background: white;
  border-radius: 16px;
  width: 500px;
  max-width: 90%;
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
  animation: slideUp 0.3s ease;
}

@keyframes slideUp {
  from { 
    opacity: 0;
    transform: translateY(30px) scale(0.95);
  }
  to { 
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.schedule-dialog {
  width: 600px;
}

.week-dialog {
  width: 450px;
}

.dialog-header {
  padding: 20px 24px;
  border-bottom: 1px solid #f1f5f9;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
  border-radius: 16px 16px 0 0;
}

.dialog-title {
  display: flex;
  align-items: center;
  gap: 12px;
}

.dialog-title h3 {
  margin: 0;
  color: #2d3748;
  font-size: 18px;
  font-weight: 600;
}

.dialog-title i {
  color: #667eea;
  font-size: 20px;
}

.dialog-close {
  background: none;
  border: none;
  font-size: 20px;
  cursor: pointer;
  color: #718096;
  padding: 8px;
  border-radius: 6px;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
}

.dialog-close:hover {
  background: #f7fafc;
  color: #4a5568;
}

.dialog-content {
  padding: 24px;
}

.form-row {
  display: flex;
  gap: 16px;
  margin-bottom: 16px;
}

.form-row .form-group {
  flex: 1;
  margin-bottom: 0;
}

.form-group {
  margin-bottom: 20px;
}

.form-group label {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  font-weight: 500;
  color: #4a5568;
  font-size: 14px;
}

.form-group label i {
  color: #667eea;
  font-size: 16px;
}

.required {
  color: #e53e3e;
  font-weight: 600;
}

.optional {
  color: #718096;
  font-weight: 400;
  font-size: 12px;
}

.form-input,
.form-select {
  width: 100%;
  padding: 12px 16px;
  border: 2px solid #e2e8f0;
  border-radius: 8px;
  box-sizing: border-box;
  font-size: 14px;
  transition: all 0.3s ease;
  background: white;
}

.form-input:focus,
.form-select:focus {
  outline: none;
  border-color: #667eea;
  box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}

.form-input:disabled {
  background: #f7fafc;
  color: #718096;
  cursor: not-allowed;
}

.input-with-suggestions {
  position: relative;
}

.form-hint {
  margin: 8px 0 0 0;
  font-size: 12px;
  color: #718096;
  line-height: 1.4;
}

.dialog-footer {
  padding: 20px 24px;
  border-top: 1px solid #f1f5f9;
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  background: #f8fafc;
  border-radius: 0 0 16px 16px;
}

.btn-primary {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border: none;
  padding: 12px 24px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  gap: 8px;
  box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
}

.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
}

.btn-secondary {
  background: white;
  color: #4a5568;
  border: 2px solid #e2e8f0;
  padding: 12px 24px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  gap: 8px;
}

.btn-secondary:hover {
  border-color: #cbd5e0;
  background: #f7fafc;
  transform: translateY(-1px);
}

/* Toast 提示消息样式 */
.toast {
  position: fixed;
  top: 20px;
  right: 20px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
  z-index: 2000;
  opacity: 0;
  transform: translateX(100%);
  transition: all 0.3s ease;
  min-width: 300px;
  max-width: 400px;
  border-left: 4px solid;
}

.toast.show {
  opacity: 1;
  transform: translateX(0);
}

.toast.success {
  border-left-color: #52c41a;
}

.toast.error {
  border-left-color: #ff4d4f;
}

.toast.warning {
  border-left-color: #faad14;
}

.toast.info {
  border-left-color: #1890ff;
}

.toast-content {
  display: flex;
  align-items: center;
  padding: 16px 20px;
  gap: 12px;
}

.toast-icon {
  font-size: 20px;
  flex-shrink: 0;
}

.toast.success .toast-icon {
  color: #52c41a;
}

.toast.error .toast-icon {
  color: #ff4d4f;
}

.toast.warning .toast-icon {
  color: #faad14;
}

.toast.info .toast-icon {
  color: #1890ff;
}

.toast-message {
  color: #2d3748;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.4;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .module-header {
    flex-direction: column;
    gap: 16px;
    align-items: stretch;
  }
  
  .header-controls {
    align-items: stretch;
  }
  
  .week-navigation {
    justify-content: center;
  }
  
  .calendar-container {
    overflow-x: auto;
  }
  
  .calendar-header,
  .calendar-row {
    min-width: 600px;
  }
  
  .dialog {
    width: 95%;
    margin: 20px;
  }
  
  .form-row {
    flex-direction: column;
    gap: 0;
  }
  
  .toast {
    right: 10px;
    left: 10px;
    min-width: auto;
  }
}

@media (max-width: 480px) {
  .module-header {
    padding: 16px;
  }
  
  .header-left h3 {
    font-size: 20px;
  }
  
  .week-indicator {
    min-width: 150px;
  }
  
  .theme-section {
    padding: 16px;
  }
  
  .dialog-content {
    padding: 16px;
  }
  
  .dialog-footer {
    padding: 16px;
    flex-direction: column-reverse;
  }
  
  .dialog-footer button {
    width: 100%;
  }
}
</style>